﻿//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;

//namespace GoldenTuney
//{


//  class StressCalculator{
      
//    private int days; // number of days to calculate stress for
//    private DateTime startDate, endDate;  // start date
//    private int shortTermDays;
//    private int longTermDays;
//    private double initialSTS;
//    private double initialLTS;
//        private double ste, lte;

//    private int lastDaysIndex;
//    private bool showSBToday;

//    // graph axis arrays
//    private List<double> stsvalues;
//    private List<double> ltsvalues;
//    private List<double> ltsramp;
//    private List<double> stsramp;
//    private List<double> sbvalues;
//    private List<double> xdays;
//    // averaging array
//    private List<double> list;

//    void calculate(int daysIndex);
//    void addRideData(double BS, DateTime rideDate);

////    boost::shared_ptr<QSettings> settings;
     

//    //public StressCalculator(DateTime startDate, DateTime endDate,
//    //    double initialSTS, double initialLTS,
//    //    int shortTermDays, int longTermDays);

//    //void calculateStress(MainWindow ,String, const String metric);

//    // x axes:
//    List<double> getSTSvalues() { return stsvalues; }
//    List<double> getLTSvalues() { return ltsvalues; }
//    List<double> getSBvalues() { return sbvalues; }
//    List<double> getDAYvalues() { return list; }
//    List<double> getLRvalues() { return ltsramp; }
//    List<double> getSRvalues() { return stsramp; }

//    // y axis
//    List<double> getDays() { return xdays; }
//    int n() { return days; }

//    // for scaling
//    double min();
//    double max();

//    // for scale
//    DateTime getStartDate() { return this.startDate; }
//    DateTime getEndDate() { return startDate.AddDays(days); }

//    // use metricDB pre-calculated values
//    MetricAggregator metricDB;

//      public StressCalculator (	DateTime startDate,	DateTime endDate, double initialSTS = 0,	double initialLTS = 0,	int shortTermDays = 7, //int longTermDays = 42) : 
//    //startDate(startDate), endDate(endDate), shortTermDays(shortTermDays),
//    //longTermDays(longTermDays),
//    //initialSTS(initialSTS), initialLTS(initialLTS), lastDaysIndex(-1)
//{
//    // calc SB for today or tomorrow?
      
//          //todo
//    //settings = GetApplicationSettings();
//    showSBToday =true;// settings.value(GC_SB_TODAY).toInt();

//    days = startDate.daysTo(endDate);

//    // make vectors 1 larger in case there is a ride for today.
//    // see calculateStress()
//    stsvalues.Capacity=(days+2);
//    ltsvalues.Capacity=(days+2);
//    sbvalues.Capacity=(days+2);
//    xdays.Capacity=(days+2);
//    list.Capacity=(days+2);
//    ltsramp.Capacity=(days+2);
//    stsramp.Capacity=(days+2);

//    lte = (double)Math.Exp(-1.0/longTermDays);
//    ste = (double)Math.Exp(-1.0/shortTermDays);
//}

//private settings GetApplicationSettings()
//{
//    throw new NotImplementedException();
//}


//double max() {
//    double max = 0.0;
//    for(int i = 0; i < days; i++) {
//    if (stsvalues[i] > max)  max = stsvalues[i];
//    if (ltsvalues[i] > max)  max = ltsvalues[i]; // unlikely..
//    if (sbvalues[i] > max)  max = sbvalues[i]; // really unlikely.
//    }
//    return max;
//}


//double min() {
//    double min = 100.0;
//    for(int i = 0; i < days; i++) {
//    if (sbvalues[i] < min)  min = sbvalues[i];
//    if (ltsvalues[i] < min)  min = ltsvalues[i]; // unlikely..
//    if (stsvalues[i] < min)  min = stsvalues[i]; // really unlikely
//    }
//    return min;
//}



//void calculateStress(MainWindow *main, QString home, const String metric)
//{
//    // get all metric data from the year 1900 - 3000
//    List<SummaryMetrics> results;

//    // refresh metrics
//    metricDB = new MetricAggregator(main, home, main->zones(), main->hrZones());
//    results = metricDB->getAllMetricsFor(QDateTime(QDate(1900,1,1)), QDateTime(QDate(3000,1,1)));
//    delete metricDB;

//    if (results.count() == 0) return; // no ride files found

//    // set start and enddate to maximum maximum required date range
//    // remember the date range required so we can truncate afterwards
//    DateTime startDateNeeded = startDate;
//    DateTime endDateNeeded   = endDate;
//    startDate = startDate < results[0].getRideDate() ? startDate : results[0].getRideDate();
//    endDate   = endDate > results[results.count()-1].getRideDate() ? endDate : results[results.count()-1].getRideDate();

//    int maxarray = startDate.daysTo(endDate) +2; // from zero plus tomorrows SB!
//    stsvalues.Capacity=(maxarray);
//    ltsvalues.Capacity=(maxarray);
//    sbvalues.Capacity=(maxarray);
//    xdays.Capacity=(maxarray);
//    list.Capacity=(maxarray);
//    ltsramp.Capacity=(maxarray);
//    stsramp.Capacity=(maxarray);

//    for (int i=0; i<results.count(); i++)
//        addRideData(results[i].getForSymbol(metric), results[i].getRideDate());

//    // ensure the last day is covered ...
//    addRideData(0.0, endDate);

//    // now truncate the data series to the requested date range
//    int firstindex = startDate.daysTo(startDateNeeded);
//    int lastindex  = startDate.daysTo(endDateNeeded)+2; // for today and tomorrow SB

//    // zap the back
//    if (lastindex < maxarray) {
//        stsvalues.remove(lastindex, maxarray-lastindex);
//        ltsvalues.remove(lastindex, maxarray-lastindex);
//        sbvalues.remove(lastindex, maxarray-lastindex);
//        xdays.remove(lastindex, maxarray-lastindex);
//        list.remove(lastindex, maxarray-lastindex);
//        stsramp.remove(lastindex, maxarray-lastindex);
//        ltsramp.remove(lastindex, maxarray-lastindex);
//    }
//    // now zap the front
//    if (firstindex) {
//        stsvalues.remove(0, firstindex);
//        ltsvalues.remove(0, firstindex);
//        ltsramp.remove(0, firstindex);
//        stsramp.remove(0, firstindex);
//        sbvalues.remove(0, firstindex);
//        xdays.remove(0, firstindex);
//        list.remove(0, firstindex);
//    }

//    // reapply the requested date range
//    startDate = startDateNeeded;
//    endDate = endDateNeeded;

//    days = startDate.daysTo(endDate) + 1; // include today

//}

///*
// * calculate each day's STS and LTS.  The daily BS values are in
// * the list.  if there aren't enough days in the list yet, we fake
// * the missing days using the supplied initial value for each day.
// * STS and LTS are calculated up to but not including todays' ride.
// * if there are two rides per day the second one is added to the first
// * so the BS/day is correct.
// */
//void addRideData(double BS, DateTime rideDate) {
//    int daysIndex = startDate.daysTo(rideDate);

//    // fill in any missing days before today
//    int d;
//    for (d = lastDaysIndex + 1; d < daysIndex ; d++) {
//        list[d] = 0.0; // no ride
//        calculate(d);
//    }

//    // ignore stuff from before start date
//    if(daysIndex < 0) return;

//    // today
//    list[daysIndex] += BS;
//    calculate(daysIndex);
//    lastDaysIndex = daysIndex;
//}

//QString time_to_string(double secs) 
//{
//    QString result;
//    unsigned rounded = static_cast<unsigned>(round(secs));
//    bool needs_colon = false;
//    if (rounded >= 3600) {
//        result += QString("%1").arg(rounded / 3600);
//        rounded %= 3600;
//        needs_colon = true;
//    }
//    if (needs_colon)
//        result += ":";
//    result += QString("%1").arg(rounded / 60, 2, 10, QLatin1Char('0'));
//    rounded %= 60;
//    result += ":";
//    result += QString("%1").arg(rounded, 2, 10, QLatin1Char('0'));
//    return result;
//}

//double str_to_interval(QString s)
//{
//    QRegExp rx("(\\d+\\s*h)?\\s*(\\d{1,2}\\s*m)?\\s*(\\d{1,2})(\\.\\d+)?\\s*s");
//    rx.indexIn(s);
//    QString hour = rx.cap(1);
//    QString min = rx.cap(2);
//    QString sec = rx.cap(3) + rx.cap(4);
//    hour.chop(1);
//    min.chop(1);
//    return 3600.0 * hour.toUInt() + 60.0 * min.toUInt() + sec.toDouble();
//}

//QString interval_to_str(double secs) 
//{
//    if (secs < 60.0)
//        return QString("%1s").arg(secs, 0, 'f', 2, QLatin1Char('0'));
//    QString result;
//    unsigned rounded = static_cast<unsigned>(round(secs));
//    bool needs_colon = false;
//    if (rounded >= 3600) {
//        result += QString("%1h").arg(rounded / 3600);
//        rounded %= 3600;
//        needs_colon = true;
//    }
//    if (needs_colon || rounded >= 60) {
//        if (needs_colon)
//            result += " ";
//        result += QString("%1m").arg(rounded / 60, 2, 10, QLatin1Char('0'));
//        rounded %= 60;
//        needs_colon = true;
//    }
//    if (needs_colon)
//        result += " ";
//    result += QString("%1s").arg(rounded, 2, 10, QLatin1Char('0'));
//    return result;
//}

//DateTime convertToLocalTime(String timestamp)
//{
//    //check if the last character is Z designating the timezone to be UTC
//    if (timestamp[timestamp.size()-1].toLower()=='z')
//    {
//        QDateTime datetime = QDateTime::fromString(timestamp, Qt::ISODate);
//        datetime.setTimeSpec(Qt::UTC);
//        datetime=datetime.toLocalTime();
//        return datetime;
//    }
//    //otherwise assume the timestamp is already in local time and simply convert it
//    //something to add here would be a handler for explicitly set timezones
//    //ex: 2002-05-30T09:30:10+06:00
//    //see http://www.w3schools.com/Schema/schema_dtypes_date.asp
//    //for more on this date format
//    else
//    {
//        return QDateTime::fromString(timestamp);
//    }
///*
// * calculate stress (in Bike Score units) using
// * stress = today's BS * (1 - exp(-1/days)) + yesterday's stress * exp(-1/days)
// * where days is the time period of concern- 7 for STS and 42 for LTS.
// *
// * exp(-1/days) for short and long term is calculated when the
// * class is instantiated.
// *
// */
//void calculate(int daysIndex) {
//    double lastLTS, lastSTS;

//    // LTS
//    if (daysIndex == 0)
//        lastLTS = initialLTS;
//    else
//        lastLTS = ltsvalues[daysIndex-1];

//    ltsvalues[daysIndex] = (list[daysIndex] * (1.0 - lte)) + (lastLTS * lte);

//    // STS
//    if (daysIndex == 0)
//        lastSTS = initialSTS;
//    else
//        lastSTS = stsvalues[daysIndex-1];

//    stsvalues[daysIndex] = (list[daysIndex] * (1.0 - ste)) + (lastSTS * ste);

//    // SB (stress balance)  long term - short term
//    // XXX FIXED BUG WHERE SB WAS NOT SHOWN ON THE NEXT DAY!
//    if (daysIndex == 0) sbvalues[daysIndex]=0;
//    sbvalues[daysIndex+(showSBToday ? 0 : 1)] =  ltsvalues[daysIndex] - stsvalues[daysIndex] ;

//    // xdays
//    xdays[daysIndex] = daysIndex+1;

//    // ramp
//    if (daysIndex > 0) {
//        stsramp[daysIndex] = stsvalues[daysIndex] - stsvalues[daysIndex-1];
//        ltsramp[daysIndex] = ltsvalues[daysIndex] - ltsvalues[daysIndex-1];
//    }
//}


//};


//}
